package com.webdrider.manager.action.snippet;

import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

import com.common.dao.interfaces.IDao;
import com.common.dao.util.Criteria;
import com.common.dao.util.QueryOperation;
import com.common.manager.abstracts.AbstractManager;
import com.common.security.exceptions.DatabaseException;
import com.common.security.exceptions.ManagerException;
import com.webdrider.dao.action.snippet.ArticleTagMapDao;
import com.webdrider.manager.interfaces.IArticleTagMapManager;
import com.webdrider.manager.interfaces.ITagManager;
import com.webdrider.model.action.snippet.ArticleTagMap;
import com.webdrider.model.action.snippet.Tag;

public class ArticleTagMapManager extends AbstractManager<ArticleTagMap> implements IArticleTagMapManager {

	private IDao<ArticleTagMap> dao;
	
	public ArticleTagMapManager() {
		dao = new ArticleTagMapDao();
	}
	
	@Override
	protected IDao<ArticleTagMap> getDao() {
		return dao;
	}
	
	@Override
	public Map<Long, List<Tag>> getAllTagsByArticleIds(List<Long> articleIds) throws ManagerException {
		try {
			List<Criteria> criterias = new ArrayList<Criteria>();
			Criteria criteria = new Criteria();
			ITagManager manager = new TagManager();
			
			Map<Long, List<Tag>> result = new HashMap<Long, List<Tag>>();
			Map<Long, Tag> tags = new HashMap<Long, Tag>();
			
			criterias.add(criteria);
			criteria.setTitle(ArticleTagMap.ARTICLE_ID);
			criteria.setComma(false);
			
			for (Long articleId : articleIds) {
				criteria.setValue(articleId);
				
				List<Tag> resultTags = new ArrayList<Tag>();
				List<ArticleTagMap> articleTagMaps = dao.getByCriteria(criterias);
				
				for (ArticleTagMap articleTagMap : articleTagMaps) {
					if (tags.containsKey(articleTagMap.getTagId())) {
						resultTags.add(tags.get(articleTagMap.getTagId()));
					} else {
						Tag tag = manager.getById(articleTagMap.getTagId());
						tags.put(tag.getId(), tag);
						resultTags.add(tag);
					}
				}
				
				result.put(articleId, resultTags);
			}
			
			return result;
		} catch (DatabaseException databaseException) {
			throw new ManagerException(ManagerException.DATABASE_EXCEPTION);
		} catch (ManagerException managerException) {
			throw managerException;
		}
	}

	@Override
	public List<Tag> getTagsByArticleId(Long articleId) throws ManagerException {
		try {
			ITagManager manager = new TagManager();
			List<Criteria> criterias = new ArrayList<Criteria>();
			criterias.add(new Criteria(ArticleTagMap.ARTICLE_ID, articleId, QueryOperation.EQUALS, false));
			
			List<ArticleTagMap> articleTagMaps = dao.getByCriteria(criterias);
			List<Tag> tags = new ArrayList<Tag>();
			
			for (ArticleTagMap articleTagMap : articleTagMaps) {
				tags.add(manager.getById(articleTagMap.getTagId()));
			}
			
			return tags;			
		} catch (DatabaseException databaseException) {
			throw new ManagerException(ManagerException.DATABASE_EXCEPTION);
		} catch (ManagerException managerException) {
			throw managerException;
		}
	}

	public Map<Long, Long> getAllArticleIdsCountByTagId(List<Tag> tags) throws ManagerException {
		try {
			List<Criteria> criterias = new ArrayList<Criteria>();
			Criteria criteria = new Criteria();
			
			criterias.add(criteria);
			criteria.setTitle(ArticleTagMap.TAG_ID);
			criteria.setComma(false);
			
			Map<Long, Long> result = new HashMap<Long, Long>();
			
			for (Tag tag : tags) {
				criteria.setValue(tag.getId());
				List<ArticleTagMap> articleTagMaps = dao.getByCriteria(criterias);

				for (ArticleTagMap articleTagMap : articleTagMaps) {					
					if (result.containsKey(articleTagMap.getArticleId())) {
						Long value = result.get(articleTagMap.getArticleId());
						result.put(articleTagMap.getArticleId(), value++);
					} else {
						result.put(articleTagMap.getArticleId(), new Long(1));
					}
				}
			}
			
			return result;
		} catch (DatabaseException databaseException) {
			throw new ManagerException(ManagerException.DATABASE_EXCEPTION);
		}
	}
}
